package com.qh.resourcehub.config;

import com.qh.resourcehub.sso.utils.LocalUserInfoFilter;
import org.jasig.cas.client.authentication.AuthenticationFilter;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.session.SingleSignOutHttpSessionListener;
import org.jasig.cas.client.util.HttpServletRequestWrapperFilter;
import org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextListener;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class ApplicationConfig {
    @Value("${cas.server-url-prefix}")
    String casServerUrlPrefix;
    @Value("${cas.client-host-url}")
    String APP_URL;

    private String ignorePattern="/virtualApply/.*|/wifiApply/.*|/micro-file-ftp/api/file/callBack|/syncUnifiedUser|/userInfo/.*|/virtualExamine/.*|/wifiExamine/.*|" +
            "/upload/.*|/firewallApply/.*|/firewallExamine/.*|/vpnApply/.*|/vpnExamine/.*|/netMappingApply/.*|/netMappingExamine/.*|/accessApply/.*|/accessExamine/.*|" +
            "/sourceCodeAuditApply/.*|/sourceCodeAuditExamine/.*|/securityAssessmentApply/.*|/securityAssessmentExamine/.*|/cleanReaded|/testPushTodo";
    @Bean
    public RequestContextListener requestContextListener() {
        return new RequestContextListener();
    }

    @Bean
    public CorsFilter corsConfigurationSource() {
        final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.addAllowedOriginPattern("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addExposedHeader("WWW-Authenticate");
        corsConfiguration.addAllowedMethod("*");
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(urlBasedCorsConfigurationSource);
    }

    /**
     * 单点登录退出
     * @return
     */
    @Bean
    public FilterRegistrationBean singleSignOutFilter(){
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new SingleSignOutFilter());
        registrationBean.addUrlPatterns("/*");
        registrationBean.setName("CAS Single Sign Out Filter");
        registrationBean.setOrder(1);
        return registrationBean;
    }

    @Bean
    public ServletListenerRegistrationBean servletListenerRegistrationBean(){
        ServletListenerRegistrationBean<SingleSignOutHttpSessionListener> myListener = new ServletListenerRegistrationBean<>();
        myListener.setListener(new SingleSignOutHttpSessionListener());
        myListener.setEnabled(true);
        myListener.setOrder(2);
        return myListener;
    }

    /**
     * 单点登录认证
     * @return
     */
    @Bean
    public FilterRegistrationBean authenticationFilter(){
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new AuthenticationFilter());
        registrationBean.addUrlPatterns("/*");
        registrationBean.setName("CAS Filter");
        registrationBean.addInitParameter("casServerUrlPrefix", casServerUrlPrefix);
        registrationBean.addInitParameter("serverName", APP_URL);

        // 正确的忽略路径配置
//        registrationBean.addInitParameter("ignorePattern", "/virtualApply/.*|/wifiApply/.*|/micro-file-ftp/api/file/callBack");
//        registrationBean.addInitParameter("ignorePattern", "/virtualApply/.*|/wifiApply/.*|/micro-file-ftp/api/file/callBack|/syncUnifiedUser|/userInfo/.*|/virtualExamine/.*");
        registrationBean.addInitParameter("ignorePattern", ignorePattern);
        registrationBean.addInitParameter("ignoreUrlPatternType", "REGEX");

        registrationBean.setOrder(3);
        return registrationBean;
    }

    /**
     * 单点登录校验
     * @return
     */
    @Bean
    public FilterRegistrationBean cas20ProxyReceivingTicketValidationFilter(){
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new Cas20ProxyReceivingTicketValidationFilter());
        registrationBean.addUrlPatterns("/*");
        registrationBean.setName("CAS Validation Filter");
        registrationBean.addInitParameter("casServerUrlPrefix", casServerUrlPrefix);
        registrationBean.addInitParameter("serverName", APP_URL);

        // 同样要配置忽略路径
//        registrationBean.addInitParameter("ignorePattern", "/virtualApply/.*|/wifiApply/.*|/syncUnifiedUser/.*|/micro-file-ftp/api/file/callBack");
//        registrationBean.addInitParameter("ignorePattern", "/virtualApply/.*|/wifiApply/.*|/micro-file-ftp/api/file/callBack|/syncUnifiedUser|/userInfo/.*|/virtualExamine/.*");
        registrationBean.addInitParameter("ignorePattern", ignorePattern);
        registrationBean.addInitParameter("ignoreUrlPatternType", "REGEX");

        registrationBean.setOrder(4);
        return registrationBean;
    }

    /**
     * 单点登录请求包装
     * @return
     */
    @Bean
    public FilterRegistrationBean httpServletRequestWrapperFilter(){
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new HttpServletRequestWrapperFilter());
        registrationBean.addUrlPatterns("/*");
        registrationBean.setName("CAS HttpServletRequest Wrapper Filter");
        registrationBean.setOrder(5); // 请求包装过滤器顺序
        return registrationBean;
    }

    @Bean
    public FilterRegistrationBean localUserInfoFilter(){
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new LocalUserInfoFilter());
        registrationBean.addUrlPatterns("/*");
        registrationBean.setName("localUserInfoFilter");
        registrationBean.setOrder(6); // 本地用户信息过滤器顺序
        return registrationBean;
    }
}
